module AboutYou
  ###
  # The SDK namespace
  ###
  module SDK
    ###
    # This Class manages the API-Calls
    #
    # Author:: Collins GmbH & Co KG
    ###
    class Client
      # url for staging-api-requests
      API_ENDPOINT_STAGE   = 'http://shop-api.staging.aboutyou.de/api'
      # url for sandbox-api-requests
      API_ENDPOINT_SANDBOX = 'http://shop-api.sandbox.aboutyou.de/api'
      # url for live-api-requests
      API_ENDPOINT_LIVE    = 'https://shop-api.aboutyou.de/api'

      # the app id of the app which should be represented by an instance of AY
      attr_accessor :app_id
      # the authentifaction token from dev-center for the app id
      attr_accessor :app_password
      # the url used for api calls
      attr_accessor :api_endpoint
      # the page id of the current page visited by an user
      attr_accessor :page_id

      ###
      # the Constructor for the Client class
      #
      # * *Args*    :
      #   - +app_id+ -> The App-Id of the App
      #   - +app_password+ -> The Auth-Token of the App
      #   - +api_endpoint+ -> Can be either live or staging
      #   - +logger+ -> Logger-Template
      #
      # * *Returns* :
      #   - Instance of AboutYou::SDK::Client
      ###
      def initialize(
        app_id,
        app_password,
        _api_endpoint = 'stage',
        _logger = nil
      )
        self.app_id = app_id
        self.app_password = app_password
      end

      ###
      # Setter for app-credentials
      #
      # * *Args*    :
      #   - +app_id+ -> The App-Id of the App
      #   - +app_password+ -> The Auth-Token of the App
      ###
      def app_credentials=(app_id, app_password)
        self.app_id = app_id
        self.app_password = app_password
      end

      ###
      # Setter for the api endpoint
      #
      # * *Args*    :
      #   - +api_endpoint+ -> Can be either live or staging
      ###
      def api_endpoint=(api_endpoint)
        case
        when api_endpoint == 'stage'
          self.api_endpoint = API_ENDPOINT_STAGE
        when api_endpoint == 'sandbox'
          self.api_endpoint = API_ENDPOINT_SANDBOX
        when api_endpoint == 'live'
          self.api_endpoint = API_ENDPOINT_LIVE
        else
          self.api_endpoint = api_endpoint
        end
      end

      ###
      # Builds a JSON string representing the request-data
      # Executes the API request
      # builds a JSON string representing the response-data
      #
      # * *Args*    :
      #   - +body+ -> the body of the api-call, containing all request data
      #
      # * *Fails* :
      #   - if the http response code is not between 200 and 300 or 304
      #   - if the body of the http response is not an array
      #
      # * *Returns* :
      #   - Json-String containing the response-body
      ###
      def request(body)
        if page_id
          request = {
            body: body,
            basic_auth: {
              username: app_id,
              password: app_password
            },
            headers: {
              'Content-Type' => 'application/json',
              'Accept-Encoding' => 'gzip,deflate',
              'X-Page-ID' => page_id
            }
          }
        else
          request = {
            body: body,
            basic_auth: {
              username: app_id,
              password: app_password
            },
            headers: {
              'Content-Type' => 'application/json',
              'Accept-Encoding' => 'gzip,deflate'
            }
          }
        end

        response = HTTParty.post('https://shop-api.aboutyou.de/api', request)
        code = response.code

        fail String(response.code) unless
        code >= 200 && code < 300 || code == 304
        fail 'result is not array' unless JSON.parse(response.body).is_a?(Array)

        JSON.parse(response.body)
      end
    end
  end
end
